package com.blandware.atleap.webapp.taglib.core.logic;

import com.blandware.atleap.common.Constants;
import com.blandware.atleap.webapp.util.core.SslUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.util.HashMap;
import java.util.Map;


/**
 * This tag library is designed to be used on a JSP
 * to switch HTTP -> HTTPS protocols and vice versa.
 * <p>If you want to force the page to be viewed in SSL,
 * then you would do something like this:<br /><br />
 * <pre>
 * &lt;tag:secure /&gt;
 * or
 * &lt;tag:secure mode="secured" /&gt;
 * </pre>
 * If you want the force the page to be viewed in
 * over standard http, then you would do something like:<br />
 * <pre>
 * &lt;tag:secure mode="unsecured" /&gt;
 * </pre>
 *
 * @author <a href="mailto:jon.lipsky@xesoft.com">Jon Lipsky</a>
 *         <p>Contributed by:
 *         <p>XEsoft GmbH
 *         Oskar-Messter-Strasse 18
 *         85737 Ismaning, Germany
 *         http://www.xesoft.com
 * @jsp.tag name="secure"
 * body-content="empty"
 */
public class SecureTag extends SimpleTagSupport {
	//~ Static fields/initializers =============================================

	public static final String MODE_SECURED = "secured";
	public static final String MODE_UNSECURED = "unsecured";
	public static final String MODE_EITHER = "either";

	//~ Instance fields ========================================================

	protected transient final Log log = LogFactory.getLog(SecureTag.class);
	protected String TAG_NAME = "Secure";
	private String mode = MODE_SECURED;
	private String httpPort = null;
	private String httpsPort = null;

	//~ Methods ================================================================

	/**
	 * Sets the mode attribute. This is included in the tld file.
	 *
	 * @jsp.attribute description="The mode attribute (secured | unsecured)"
	 * required="false"
	 * rtexprvalue="true"
	 */
	public void setMode(String aMode) {
		mode = aMode;
	}

    /**
     * Processes the tag
     *
     * @throws JspTagException
     */
	public void doTag() throws JspTagException, SkipPageException {

		PageContext pageContext = (PageContext) getJspContext();

		// get the port numbers from the application context
		Map config =
		        (HashMap) pageContext.getServletContext().getAttribute(Constants.CONFIG);

		httpPort = (String) config.get(Constants.HTTP_PORT);

		if ( httpPort == null ) {
			httpPort = SslUtil.STD_HTTP_PORT;
		}

		httpsPort = (String) config.get(Constants.HTTPS_PORT);

		if ( httpsPort == null ) {
			httpsPort = SslUtil.STD_HTTPS_PORT;
		}

		if ( mode.equalsIgnoreCase(MODE_SECURED) ) {
			if ( pageContext.getRequest().isSecure() == false ) {
				String vQueryString =
				        ((HttpServletRequest) pageContext.getRequest()).getQueryString();
				String vPageUrl =
				        ((HttpServletRequest) pageContext.getRequest()).getRequestURI();
				String vServer = pageContext.getRequest().getServerName();

				StringBuffer vRedirect = new StringBuffer("");
				vRedirect.append("https://");
				vRedirect.append(vServer + ":" + httpsPort + vPageUrl);

				if ( vQueryString != null ) {
					vRedirect.append("?");
					vRedirect.append(vQueryString);
				}

				if ( log.isDebugEnabled() ) {
					log.debug("attempting to redirect to: " + vRedirect);
				}

				try {
					((HttpServletResponse) pageContext.getResponse()).sendRedirect(vRedirect.toString());
				} catch ( Exception exc2 ) {
					throw new JspTagException(exc2.getMessage());
				}
                throw new SkipPageException();
			}
		} else if ( mode.equalsIgnoreCase(MODE_UNSECURED) ) {
			if ( pageContext.getRequest().isSecure() == true ) {
				String vQueryString =
				        ((HttpServletRequest) pageContext.getRequest()).getQueryString();
				String vPageUrl =
				        ((HttpServletRequest) pageContext.getRequest()).getRequestURI();
				String vServer = pageContext.getRequest().getServerName();

				StringBuffer vRedirect = new StringBuffer("");
				vRedirect.append("http://");
				vRedirect.append(vServer + vPageUrl);

				if ( vQueryString != null ) {
					vRedirect.append("?");
					vRedirect.append(vQueryString);
				}

				try {
					((HttpServletResponse) pageContext.getResponse()).sendRedirect(vRedirect.toString());
				} catch ( Exception exc2 ) {
					throw new JspTagException(exc2.getMessage());
				}
                throw new SkipPageException();
			}
		} else if ( !mode.equalsIgnoreCase(MODE_EITHER) ) {
			throw new JspTagException("Illegal value for the attribute mode: " +
			        mode);
		}
	}

}
